@testomatio/reporter 1.5.1-beta β 1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/lib/adapter/cucumber/current.js +2 -4
- package/lib/adapter/playwright.js +4 -1
- package/lib/bin/startTest.js +2 -2
- package/lib/client.js +6 -3
- package/lib/pipe/bitbucket.js +254 -0
- package/lib/pipe/index.js +2 -0
- package/lib/pipe/testomatio.js +9 -4
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ Testomat.io Reporter (this npm package) supports:
|
|
|
11
11
|
- π Integarion with all popular [JavaScript/TypeScript frameworks](./docs/frameworks.md)
|
|
12
12
|
- ποΈ Screenshots, videos, traces [uploaded into S3 bucket](./docs/artifacts.md)
|
|
13
13
|
- π [Stack traces](./docs/stacktrace.md) and error messages
|
|
14
|
-
- π [GitHub](./docs/pipes/github.md)
|
|
14
|
+
- π [GitHub](./docs/pipes/github.md), [GitLab](./docs/pipes/gitlab.md) & [Bitbucket](./docs/pipes/bitbucket.md) integration
|
|
15
15
|
- π
Realtime reports
|
|
16
16
|
- ποΈ Other test frameworks supported via [JUNit XML](./docs/junit.md)
|
|
17
17
|
- πΆββοΈ Steps _(work in progress)_
|
|
@@ -128,6 +128,7 @@ Bring this reporter on CI and never lose test results again!
|
|
|
128
128
|
- [Gitlab](./docs/pipes/gitlab.md)
|
|
129
129
|
- [CSV](./docs/pipes/csv.md)
|
|
130
130
|
- [HTML report](./docs/pipes/html.md)
|
|
131
|
+
- [Bitbucket](./docs/pipes/bitbucket.md)
|
|
131
132
|
- π [JUnit](./docs/junit.md)
|
|
132
133
|
- ποΈ [Artifacts](./docs/artifacts.md)
|
|
133
134
|
- π [Workflows](./docs/workflows.md)
|
|
@@ -32,16 +32,14 @@ class CucumberReporter extends Formatter {
|
|
|
32
32
|
|
|
33
33
|
this.client = new TestomatClient({ apiKey: options.apiKey || config.TESTOMATIO });
|
|
34
34
|
this.status = STATUS.PASSED;
|
|
35
|
+
this.client.createRun();
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
parseEnvelope(envelope) {
|
|
38
39
|
if (envelope.testRunStarted) {
|
|
39
40
|
fileSystem.clearDir(TESTOMAT_TMP_STORAGE_DIR);
|
|
40
41
|
}
|
|
41
|
-
if (envelope.testCaseStarted && this.client)
|
|
42
|
-
this.client.createRun();
|
|
43
|
-
this.onTestCaseStarted(envelope.testCaseStarted);
|
|
44
|
-
}
|
|
42
|
+
if (envelope.testCaseStarted && this.client) this.onTestCaseStarted(envelope.testCaseStarted);
|
|
45
43
|
if (envelope.testCaseFinished) this.onTestCaseFinished(envelope.testCaseFinished);
|
|
46
44
|
if (envelope.testRunFinished) this.onTestRunFinished(envelope);
|
|
47
45
|
}
|
|
@@ -147,6 +147,9 @@ function checkStatus(status) {
|
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
function appendStep(step, shift = 0) {
|
|
150
|
+
// nesting too deep, ignore those steps
|
|
151
|
+
if (shift >= 10) return;
|
|
152
|
+
|
|
150
153
|
let newCategory = step.category;
|
|
151
154
|
switch (newCategory) {
|
|
152
155
|
case 'test.step':
|
|
@@ -176,7 +179,7 @@ function appendStep(step, shift = 0) {
|
|
|
176
179
|
};
|
|
177
180
|
|
|
178
181
|
if (formattedSteps.length) {
|
|
179
|
-
resultStep.steps = formattedSteps;
|
|
182
|
+
resultStep.steps = formattedSteps.filter(s => !!s);
|
|
180
183
|
}
|
|
181
184
|
|
|
182
185
|
if (step.error !== undefined) {
|
package/lib/bin/startTest.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const
|
|
2
|
+
const spawn = require('cross-spawn');
|
|
3
3
|
const program = require('commander');
|
|
4
4
|
const chalk = require('chalk');
|
|
5
5
|
const TestomatClient = require('../client');
|
|
@@ -45,7 +45,7 @@ program
|
|
|
45
45
|
|
|
46
46
|
const client = new TestomatClient({ apiKey });
|
|
47
47
|
|
|
48
|
-
client.updateRunStatus(STATUS.FINISHED
|
|
48
|
+
client.updateRunStatus(STATUS.FINISHED).then(() => {
|
|
49
49
|
console.log(chalk.yellow(`Run ${process.env.TESTOMATIO_RUN} was finished`));
|
|
50
50
|
process.exit(0);
|
|
51
51
|
});
|
package/lib/client.js
CHANGED
|
@@ -279,7 +279,10 @@ class Client {
|
|
|
279
279
|
logs = logs?.trim();
|
|
280
280
|
|
|
281
281
|
if (Array.isArray(steps)) {
|
|
282
|
-
steps = steps
|
|
282
|
+
steps = steps
|
|
283
|
+
.map(step => formatStep(step))
|
|
284
|
+
.flat()
|
|
285
|
+
.join('\n');
|
|
283
286
|
}
|
|
284
287
|
|
|
285
288
|
let testLogs = '';
|
|
@@ -358,8 +361,8 @@ function formatStep(step, shift = 0) {
|
|
|
358
361
|
|
|
359
362
|
for (const child of step.steps || []) {
|
|
360
363
|
lines.push(...formatStep(child, shift + 2));
|
|
361
|
-
}
|
|
362
|
-
|
|
364
|
+
}
|
|
365
|
+
|
|
363
366
|
return lines;
|
|
364
367
|
}
|
|
365
368
|
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
const debug = require('debug')('@testomatio/reporter:pipe:bitbucket');
|
|
2
|
+
const { default: axios } = require('axios');
|
|
3
|
+
const chalk = require('chalk');
|
|
4
|
+
const humanizeDuration = require('humanize-duration');
|
|
5
|
+
const merge = require('lodash.merge');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const { APP_PREFIX, testomatLogoURL } = require('../constants');
|
|
8
|
+
const { ansiRegExp, isSameTest } = require('../utils/utils');
|
|
9
|
+
const { statusEmoji, fullName } = require('../utils/pipe_utils');
|
|
10
|
+
|
|
11
|
+
//! BITBUCKET_ACCESS_TOKEN environment variable is required for this functionality to work
|
|
12
|
+
//! and your pipeline trigger should be a pull request
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @class BitbucketPipe
|
|
16
|
+
* @typedef {import('../../types').Pipe} Pipe
|
|
17
|
+
* @typedef {import('../../types').TestData} TestData
|
|
18
|
+
*/
|
|
19
|
+
class BitbucketPipe {
|
|
20
|
+
constructor(params, store = {}) {
|
|
21
|
+
this.isEnabled = false;
|
|
22
|
+
this.ENV = process.env;
|
|
23
|
+
this.store = store;
|
|
24
|
+
this.tests = [];
|
|
25
|
+
// Bitbucket PAT looks like bbpat-*****
|
|
26
|
+
this.token = params.BITBUCKET_ACCESS_TOKEN || process.env.BITBUCKET_ACCESS_TOKEN || this.ENV.BITBUCKET_ACCESS_TOKEN;
|
|
27
|
+
this.hiddenCommentData = `Testomat.io report: ${process.env.BITBUCKET_BRANCH || ''}`;
|
|
28
|
+
|
|
29
|
+
debug(
|
|
30
|
+
chalk.yellow('Bitbucket Pipe:'),
|
|
31
|
+
this.token ? 'TOKEN passed' : '*no token*',
|
|
32
|
+
`Project key: ${this.ENV.BITBUCKET_PROJECT_KEY}, Pull request ID: ${this.ENV.BITBUCKET_PR_ID}`,
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
if (!this.token) {
|
|
36
|
+
debug(`Hint: Bitbucket CI variables are unavailable for unprotected branches by default.`);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
this.isEnabled = true;
|
|
41
|
+
|
|
42
|
+
debug('Bitbucket Pipe: Enabled');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async cleanLog(log) {
|
|
46
|
+
const stripAnsi = (await import('strip-ansi')).default;
|
|
47
|
+
return stripAnsi(log);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Prepare the run (if needed)
|
|
51
|
+
async prepareRun() {}
|
|
52
|
+
|
|
53
|
+
// Create a new run (if needed)
|
|
54
|
+
async createRun() {}
|
|
55
|
+
|
|
56
|
+
addTest(test) {
|
|
57
|
+
if (!this.isEnabled) return;
|
|
58
|
+
|
|
59
|
+
const index = this.tests.findIndex(t => isSameTest(t, test));
|
|
60
|
+
// Update if they were already added
|
|
61
|
+
if (index >= 0) {
|
|
62
|
+
this.tests[index] = merge(this.tests[index], test);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
this.tests.push(test);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async finishRun(runParams) {
|
|
70
|
+
if (!this.isEnabled) return;
|
|
71
|
+
|
|
72
|
+
if (runParams.tests) runParams.tests.forEach(t => this.addTest(t));
|
|
73
|
+
|
|
74
|
+
// Clean up the logs from ANSI codes
|
|
75
|
+
for (let i = 0; i < this.tests.length; i++) {
|
|
76
|
+
this.tests[i].message = await this.cleanLog(this.tests[i].message || '');
|
|
77
|
+
this.tests[i].stack = await this.cleanLog(this.tests[i].stack || '');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Create a comment on Bitbucket
|
|
81
|
+
const passedCount = this.tests.filter(t => t.status === 'passed').length;
|
|
82
|
+
const failedCount = this.tests.filter(t => t.status === 'failed').length;
|
|
83
|
+
const skippedCount = this.tests.filter(t => t.status === 'skipped').length;
|
|
84
|
+
|
|
85
|
+
// Constructing the table
|
|
86
|
+
let summary = `${this.hiddenCommentData}
|
|
87
|
+
|
|
88
|
+
|  | ${statusEmoji(
|
|
89
|
+
runParams.status,
|
|
90
|
+
)} ${runParams.status.toUpperCase()} ${statusEmoji(runParams.status)} |
|
|
91
|
+
| --- | --- |
|
|
92
|
+
| **Tests** | βοΈ **${this.tests.length}** tests run |
|
|
93
|
+
| **Summary** | ${statusEmoji('failed')} **${failedCount}** failed; ${statusEmoji(
|
|
94
|
+
'passed',
|
|
95
|
+
)} **${passedCount}** passed; **${statusEmoji('skipped')}** ${skippedCount} skipped |
|
|
96
|
+
| **Duration** | π **${humanizeDuration(
|
|
97
|
+
parseInt(
|
|
98
|
+
this.tests.reduce((a, t) => a + (t.run_time || 0), 0),
|
|
99
|
+
10,
|
|
100
|
+
),
|
|
101
|
+
{
|
|
102
|
+
maxDecimalPoints: 0,
|
|
103
|
+
},
|
|
104
|
+
)}** |
|
|
105
|
+
`;
|
|
106
|
+
|
|
107
|
+
if (this.ENV.BITBUCKET_BRANCH && this.ENV.BITBUCKET_COMMIT) {
|
|
108
|
+
// eslint-disable-next-line max-len
|
|
109
|
+
summary += `| **Job** | π· [#${this.ENV.BITBUCKET_BUILD_NUMBER}](https://bitbucket.org/${this.ENV.BITBUCKET_REPO_FULL_NAME}/pipelines/results/${this.ENV.BITBUCKET_BUILD_NUMBER}") by commit: **${this.ENV.BITBUCKET_COMMIT}** |`;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const failures = this.tests
|
|
113
|
+
.filter(t => t.status === 'failed')
|
|
114
|
+
.slice(0, 20)
|
|
115
|
+
.map(t => {
|
|
116
|
+
let text = `${statusEmoji('failed')} ${fullName(t)}\n`;
|
|
117
|
+
if (t.message) {
|
|
118
|
+
text += `> ${t.message
|
|
119
|
+
.replace(/[^\x20-\x7E]/g, '')
|
|
120
|
+
.replace(ansiRegExp(), '')
|
|
121
|
+
.trim()}\n`;
|
|
122
|
+
}
|
|
123
|
+
if (t.stack) {
|
|
124
|
+
text += `\n\`\`\`diff\n${t.stack
|
|
125
|
+
.replace(ansiRegExp(), '')
|
|
126
|
+
.replace(
|
|
127
|
+
/^[\s\S]*################\[ Failure \]################/g,
|
|
128
|
+
'################[ Failure ]################',
|
|
129
|
+
)
|
|
130
|
+
.trim()}\n\`\`\`\n`;
|
|
131
|
+
}
|
|
132
|
+
if (t.artifacts && t.artifacts.length && !this.ENV.TESTOMATIO_PRIVATE_ARTIFACTS) {
|
|
133
|
+
t.artifacts
|
|
134
|
+
.filter(f => !!f)
|
|
135
|
+
.forEach(f => {
|
|
136
|
+
if (f.endsWith('.png')) {
|
|
137
|
+
text += `\n`;
|
|
138
|
+
} else {
|
|
139
|
+
text += `[π ${path.basename(f)}](${f})\n`;
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
text += `\n---\n`;
|
|
144
|
+
return text;
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
let body = summary;
|
|
148
|
+
|
|
149
|
+
if (failures.length) {
|
|
150
|
+
body += `\nπ₯ **Failures (${failures.length})**\n\n* ${failures.join('\n* ')}\n`;
|
|
151
|
+
if (failures.length > 10) {
|
|
152
|
+
body += `\n> Notice: Only the first 10 failures are shown.`;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (this.tests.length > 0) {
|
|
157
|
+
body += `\n\n**π’ Slowest Tests**\n\n`;
|
|
158
|
+
body += this.tests
|
|
159
|
+
.sort((a, b) => b.run_time - a.run_time)
|
|
160
|
+
.slice(0, 5)
|
|
161
|
+
.map(t => `* **${fullName(t)}** (${humanizeDuration(parseFloat(t.run_time))})`)
|
|
162
|
+
.join('\n');
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Construct Bitbucket API URL for comments
|
|
166
|
+
// eslint-disable-next-line max-len
|
|
167
|
+
const commentsRequestURL = `https://api.bitbucket.org/2.0/repositories/${this.ENV.BITBUCKET_WORKSPACE}/${this.ENV.BITBUCKET_REPO_SLUG}/pullrequests/${this.ENV.BITBUCKET_PR_ID}/comments`;
|
|
168
|
+
|
|
169
|
+
// Delete previous report
|
|
170
|
+
await deletePreviousReport(axios, commentsRequestURL, this.hiddenCommentData, this.token);
|
|
171
|
+
|
|
172
|
+
// Add current report
|
|
173
|
+
debug(`Adding comment via URL: ${commentsRequestURL}`);
|
|
174
|
+
debug(`Final Bitbucket API call body: ${body}`);
|
|
175
|
+
|
|
176
|
+
try {
|
|
177
|
+
const addCommentResponse = await axios.post(
|
|
178
|
+
commentsRequestURL,
|
|
179
|
+
{ content: { raw: body } },
|
|
180
|
+
{
|
|
181
|
+
headers: {
|
|
182
|
+
Authorization: `Bearer ${this.token}`,
|
|
183
|
+
'Content-Type': 'application/json',
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
const commentID = addCommentResponse.data.id;
|
|
189
|
+
// eslint-disable-next-line max-len
|
|
190
|
+
const commentURL = `https://bitbucket.org/${this.ENV.BITBUCKET_WORKSPACE}/${this.ENV.BITBUCKET_REPO_SLUG}/pull-requests/${this.ENV.BITBUCKET_PR_ID}#comment-${commentID}`;
|
|
191
|
+
|
|
192
|
+
console.log(APP_PREFIX, chalk.yellow('Bitbucket'), `Report created: ${chalk.magenta(commentURL)}`);
|
|
193
|
+
} catch (err) {
|
|
194
|
+
console.error(
|
|
195
|
+
APP_PREFIX,
|
|
196
|
+
chalk.yellow('Bitbucket'),
|
|
197
|
+
`Couldn't create Bitbucket report\n${err}.
|
|
198
|
+
Request URL: ${commentsRequestURL}
|
|
199
|
+
Request data: ${body}`,
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
toString() {
|
|
205
|
+
return 'Bitbucket Reporter';
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
updateRun() {}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
async function deletePreviousReport(axiosInstance, commentsRequestURL, hiddenCommentData, token) {
|
|
212
|
+
if (process.env.BITBUCKET_KEEP_OUTDATED_REPORTS) return;
|
|
213
|
+
|
|
214
|
+
// Get comments
|
|
215
|
+
let comments = [];
|
|
216
|
+
|
|
217
|
+
try {
|
|
218
|
+
const response = await axiosInstance.get(commentsRequestURL, {
|
|
219
|
+
headers: {
|
|
220
|
+
Authorization: `Bearer ${token}`,
|
|
221
|
+
'Content-Type': 'application/json',
|
|
222
|
+
},
|
|
223
|
+
});
|
|
224
|
+
comments = response.data.values;
|
|
225
|
+
} catch (e) {
|
|
226
|
+
console.error('Error while attempting to retrieve comments on Bitbucket Pull Request:\n', e);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (!comments.length) return;
|
|
230
|
+
|
|
231
|
+
for (const comment of comments) {
|
|
232
|
+
// If comment was left by the same workflow
|
|
233
|
+
if (comment.content.raw.includes(hiddenCommentData)) {
|
|
234
|
+
try {
|
|
235
|
+
// Delete previous comment
|
|
236
|
+
const deleteCommentURL = `${commentsRequestURL}/${comment.id}`;
|
|
237
|
+
await axiosInstance.delete(deleteCommentURL, {
|
|
238
|
+
headers: {
|
|
239
|
+
Authorization: `Bearer ${token}`,
|
|
240
|
+
'Content-Type': 'application/json',
|
|
241
|
+
},
|
|
242
|
+
});
|
|
243
|
+
} catch (e) {
|
|
244
|
+
console.warn(`Can't delete previously added comment with testomat.io report. Ignored.`);
|
|
245
|
+
}
|
|
246
|
+
// Pass next env var if need to clear all previous reports;
|
|
247
|
+
// only the last one is removed by default
|
|
248
|
+
if (!process.env.BITBUCKET_REMOVE_ALL_OUTDATED_REPORTS) break;
|
|
249
|
+
// TODO: in case of many reports should implement pagination
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
module.exports = BitbucketPipe;
|
package/lib/pipe/index.js
CHANGED
|
@@ -7,6 +7,7 @@ const GitHubPipe = require('./github');
|
|
|
7
7
|
const GitLabPipe = require('./gitlab');
|
|
8
8
|
const CsvPipe = require('./csv');
|
|
9
9
|
const HtmlPipe = require('./html');
|
|
10
|
+
const BitbucketPipe = require('./bitbucket');
|
|
10
11
|
|
|
11
12
|
function PipeFactory(params, opts) {
|
|
12
13
|
const extraPipes = [];
|
|
@@ -45,6 +46,7 @@ function PipeFactory(params, opts) {
|
|
|
45
46
|
new GitLabPipe(params, opts),
|
|
46
47
|
new CsvPipe(params, opts),
|
|
47
48
|
new HtmlPipe(params, opts),
|
|
49
|
+
new BitbucketPipe(params, opts),
|
|
48
50
|
...extraPipes,
|
|
49
51
|
];
|
|
50
52
|
|
package/lib/pipe/testomatio.js
CHANGED
|
@@ -50,6 +50,7 @@ class TestomatioPipe {
|
|
|
50
50
|
this.store = store || {};
|
|
51
51
|
this.title = params.title || process.env.TESTOMATIO_TITLE;
|
|
52
52
|
this.sharedRun = !!process.env.TESTOMATIO_SHARED_RUN;
|
|
53
|
+
this.sharedRunTimeout = !!process.env.TESTOMATIO_SHARED_RUN_TIMEOUT;
|
|
53
54
|
this.groupTitle = params.groupTitle || process.env.TESTOMATIO_RUNGROUP_TITLE;
|
|
54
55
|
this.env = process.env.TESTOMATIO_ENV;
|
|
55
56
|
this.label = process.env.TESTOMATIO_LABEL;
|
|
@@ -184,6 +185,7 @@ class TestomatioPipe {
|
|
|
184
185
|
title: this.title,
|
|
185
186
|
label: this.label,
|
|
186
187
|
shared_run: this.sharedRun,
|
|
188
|
+
shared_run_timeout: this.sharedRunTimeout,
|
|
187
189
|
}).filter(([, value]) => !!value),
|
|
188
190
|
);
|
|
189
191
|
debug('Run params', JSON.stringify(runParams, null, 2));
|
|
@@ -214,10 +216,11 @@ class TestomatioPipe {
|
|
|
214
216
|
process.env.runId = this.runId;
|
|
215
217
|
debug('Run created', this.runId);
|
|
216
218
|
} catch (err) {
|
|
219
|
+
const errorInfo = `${err?.response?.statusText} ${chalk.red(err?.status)} ${err.message}`;
|
|
217
220
|
console.error(
|
|
218
221
|
APP_PREFIX,
|
|
219
|
-
'Error creating Testomat.io report, please check if your API key is valid. Skipping report
|
|
220
|
-
|
|
222
|
+
'Error creating Testomat.io report, please check if your API key is valid. Skipping report\n',
|
|
223
|
+
errorInfo || JSON.stringify(err),
|
|
221
224
|
);
|
|
222
225
|
printCreateIssue(err);
|
|
223
226
|
}
|
|
@@ -296,7 +299,7 @@ class TestomatioPipe {
|
|
|
296
299
|
}
|
|
297
300
|
});
|
|
298
301
|
};
|
|
299
|
-
|
|
302
|
+
|
|
300
303
|
|
|
301
304
|
/**
|
|
302
305
|
* Uploads tests as a batch (multiple tests at once). Intended to be used with a setInterval
|
|
@@ -310,6 +313,8 @@ class TestomatioPipe {
|
|
|
310
313
|
const testsToSend = this.batch.tests.splice(0);
|
|
311
314
|
debug('π¨ Batch upload', testsToSend.length, 'tests');
|
|
312
315
|
|
|
316
|
+
testsToSend.forEach(debug);
|
|
317
|
+
|
|
313
318
|
return this.axios
|
|
314
319
|
.post(
|
|
315
320
|
`/api/reporter/${this.runId}/testrun`,
|
|
@@ -367,7 +372,7 @@ class TestomatioPipe {
|
|
|
367
372
|
*/
|
|
368
373
|
async finishRun(params) {
|
|
369
374
|
if (!this.isEnabled) return;
|
|
370
|
-
|
|
375
|
+
|
|
371
376
|
await this.#batchUpload();
|
|
372
377
|
if (this.batch.intervalFunction) clearInterval(this.batch.intervalFunction);
|
|
373
378
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@testomatio/reporter",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.2",
|
|
4
4
|
"description": "Testomatio Reporter Client",
|
|
5
5
|
"main": "./lib/reporter.js",
|
|
6
6
|
"typings": "typings/index.d.ts",
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
"callsite-record": "^4.1.4",
|
|
18
18
|
"chalk": "^4.1.0",
|
|
19
19
|
"commander": "^4.1.1",
|
|
20
|
+
"cross-spawn": "^7.0.3",
|
|
20
21
|
"csv-writer": "^1.6.0",
|
|
21
22
|
"debug": "^4.3.4",
|
|
22
23
|
"dotenv": "^16.0.1",
|
|
@@ -32,6 +33,7 @@
|
|
|
32
33
|
"lodash.merge": "^4.6.2",
|
|
33
34
|
"minimatch": "^9.0.3",
|
|
34
35
|
"promise-retry": "^2.0.1",
|
|
36
|
+
"strip-ansi": "^7.1.0",
|
|
35
37
|
"uuid": "^9.0.0"
|
|
36
38
|
},
|
|
37
39
|
"files": [
|